import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'dart:convert';
import 'dart:io';
import '../../core/config/app_config.dart';
import '../../core/constants/api_endpoints.dart';
import '../../core/services/image_cache_service.dart';
import '../../core/di/service_locator.dart';

/// Markdown 消息组件
/// 支持 Markdown 格式的消息渲染，包括：
/// - 文本格式化（粗体、斜体、代码等）
/// - 链接
/// - 图片
/// - 代码块
/// - 列表等
class MarkdownMessage extends StatelessWidget {
  final String content;
  final bool isSent;
  final String? fileUrl;
  final String? fileName;
  final String? fileType;
  final int? messageContentType; // 1=文本, 2=图片, 3=文件
  final Color? backgroundColor;
  final Color? textColor;

  const MarkdownMessage({
    super.key,
    required this.content,
    this.isSent = false,
    this.fileUrl,
    this.fileName,
    this.fileType,
    this.messageContentType,
    this.backgroundColor,
    this.textColor,
  });

  /// 判断是否为图片
  bool get _isImage {
    // 优先使用 message_content_type 判断
    if (messageContentType == 2) {
      return true;
    }

    if (fileType != null) {
      return fileType!.startsWith('image/');
    }

    final url = fileUrl ?? _extractFileUrl();
    if (url.isEmpty) return false;

    final lowerUrl = url.toLowerCase();
    // 检查是否是 base64 data URI 图片
    if (lowerUrl.startsWith('data:image/')) {
      return true;
    }
    // 检查是否是图片 URL
    final imageExtPattern = RegExp(r'\.(jpg|jpeg|png|gif|webp|bmp|svg)(\?|$)', caseSensitive: false);
    return imageExtPattern.hasMatch(lowerUrl);
  }

  /// 从 content 中提取文件/图片 URL
  String _extractFileUrl() {
    // 优先使用传入的 fileUrl
    if (fileUrl != null && fileUrl!.isNotEmpty) {
      // 如果是相对路径，构建完整 URL
      if (fileUrl!.startsWith('/api/upload/') || fileUrl!.startsWith('/upload/')) {
        final baseUrl = AppConfig.baseUrl;
        final port = AppConfig.serverPort;
        if (fileUrl!.startsWith('/upload/')) {
          return '$baseUrl:$port/api$fileUrl';
        } else {
          return '$baseUrl:$port$fileUrl';
        }
      }
      return fileUrl!;
    }

    if (content.isEmpty) {
      return '';
    }

    final trimmedContent = content.trim();

    // 检查是否是 base64 data URI 图片
    if (trimmedContent.startsWith('data:image/')) {
      return trimmedContent;
    }

    // 检查是否是完整的 HTTP/HTTPS URL
    if (trimmedContent.startsWith('http://') || trimmedContent.startsWith('https://')) {
      return trimmedContent;
    }

    // 检查是否是相对路径的 URL（/api/upload/ 或 /upload/）
    if (ApiEndpoints.isUploadPath(trimmedContent) || trimmedContent.startsWith('/upload/')) {
      // 构建完整 URL：baseUrl + 路径
      final baseUrl = AppConfig.baseUrl;
      final port = AppConfig.serverPort;
      if (trimmedContent.startsWith('/upload/')) {
        return '$baseUrl:$port/api$trimmedContent';
      } else {
        return '$baseUrl:$port$trimmedContent';
      }
    }

    // 检查是否是完整的 HTTP/HTTPS 图片 URL（带扩展名）
    final httpImagePattern = RegExp(
      r'https?://[^\s]+\.(jpg|jpeg|png|gif|webp|bmp|svg)(\?[^\s]*)?',
      caseSensitive: false,
    );
    final httpMatch = httpImagePattern.firstMatch(trimmedContent);
    if (httpMatch != null) {
      return httpMatch.group(0)!;
    }

    return '';
  }

  /// 判断是否应该显示文本内容
  bool get _shouldShowContent {
    if (content.isEmpty) return false;

    // 如果是文件消息（message_content_type === 3），不显示文本内容，只显示文件名
    if (messageContentType == 3) {
      return false;
    }

    // 如果从 content 中提取到了文件/图片 URL，且 content 只包含这个 URL，则不显示文本内容
    final extractedUrl = _extractFileUrl();
    if (extractedUrl.isNotEmpty) {
      final trimmedContent = content.trim();
      // 检查 content 是否只包含 URL（可能带空格）
      if (trimmedContent == extractedUrl ||
          trimmedContent.replaceAll(RegExp(r'\s+'), '') ==
              extractedUrl.replaceAll(RegExp(r'\s+'), '')) {
        return false;
      }
    }

    // 如果是图片消息，且 content 只包含文件名，则不显示
    if (_isImage && fileName != null) {
      final trimmedContent = content.trim();
      final fileExtPattern = RegExp(r'\.(jpg|jpeg|png|gif|webp|bmp|svg)$', caseSensitive: false);
      if (trimmedContent == fileName ||
          trimmedContent == fileName!.replaceAll(fileExtPattern, '')) {
        return false;
      }
    }

    // 如果是文件消息（有 fileUrl 但不是图片），且 content 只包含文件名或 URL，则不显示
    if (!_isImage && (fileUrl != null || extractedUrl.isNotEmpty) && fileName != null) {
      final trimmedContent = content.trim();
      if (trimmedContent == fileName || trimmedContent == extractedUrl) {
        return false;
      }
    }

    return true;
  }

  /// 获取文件图标
  IconData _getFileIcon() {
    if (fileType == null) return Icons.insert_drive_file;

    if (fileType!.startsWith('image/')) {
      return Icons.image;
    } else if (fileType!.startsWith('video/')) {
      return Icons.video_file;
    } else if (fileType!.startsWith('audio/')) {
      return Icons.audio_file;
    } else if (fileType!.contains('pdf')) {
      return Icons.picture_as_pdf;
    } else if (fileType!.contains('word') || fileType!.contains('doc')) {
      return Icons.description;
    } else if (fileType!.contains('excel') || fileType!.contains('xls')) {
      return Icons.table_chart;
    } else if (fileType!.contains('zip') || fileType!.contains('rar')) {
      return Icons.archive;
    }

    return Icons.insert_drive_file;
  }

  /// 获取显示的文件名
  String _getDisplayFileName() {
    if (fileName != null && fileName!.isNotEmpty) {
      return fileName!;
    }
    if (fileUrl != null) {
      final uri = Uri.tryParse(fileUrl!);
      if (uri != null) {
        final pathSegments = uri.pathSegments;
        if (pathSegments.isNotEmpty) {
          return pathSegments.last;
        }
      }
    }
    return '文件';
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final defaultBackgroundColor = backgroundColor ?? (isSent
        ? theme.colorScheme.primary
        : Colors.grey[200]!);
    final defaultTextColor = textColor ?? (isSent
        ? Colors.white
        : Colors.black87);

    // 检查是否有文件 URL（图片或文件）
    final extractedFileUrl = _extractFileUrl();
    final hasFileUrl = extractedFileUrl.isNotEmpty || fileUrl != null;
    final isFileMessage = messageContentType == 3 || (!_isImage && hasFileUrl);

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        // 图片预览
        if (_isImage && extractedFileUrl.isNotEmpty)
          _buildImagePreview(context),

        // 文件链接（非图片文件）
        if (!_isImage && isFileMessage && hasFileUrl)
          _buildFilePreview(context, defaultTextColor),

        // Markdown 文本内容
        if (_shouldShowContent)
          _buildMarkdownContent(
            context,
            defaultBackgroundColor,
            defaultTextColor,
          ),
      ],
    );
  }

  Widget _buildImagePreview(BuildContext context) {
    final imageUrl = _extractFileUrl();
    if (imageUrl.isEmpty) return const SizedBox.shrink();

    // base64 图片直接显示
    if (imageUrl.startsWith('data:image/')) {
      return Container(
        margin: const EdgeInsets.only(bottom: 8),
        constraints: const BoxConstraints(
          maxWidth: 250,
          maxHeight: 300,
        ),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(8),
          border: Border.all(
            color: Colors.grey[300]!,
            width: 1,
          ),
        ),
        child: ClipRRect(
          borderRadius: BorderRadius.circular(8),
          child: Image.memory(
            UriData.fromString(imageUrl).contentAsBytes(),
            fit: BoxFit.cover,
            errorBuilder: (context, error, stackTrace) {
              return Container(
                padding: const EdgeInsets.all(16),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Icon(Icons.broken_image, color: Colors.grey[400]),
                    const SizedBox(height: 8),
                    Text(
                      '图片加载失败',
                      style: TextStyle(
                        color: Colors.grey[600],
                        fontSize: 12,
                      ),
                    ),
                  ],
                ),
              );
            },
          ),
        ),
      );
    }

    // 检查是否是本地文件路径（file:// 或绝对路径）
    if (imageUrl.startsWith('file://') || 
        (imageUrl.startsWith('/') && !imageUrl.startsWith('http'))) {
      // 处理本地文件路径
      String localPath = imageUrl;
      if (localPath.startsWith('file://')) {
        localPath = localPath.substring(7); // 移除 file:// 前缀
        // 检查路径是否有效（file:///screenshot.png 这种格式无效）
        // 如果移除 file:// 后路径不是有效的绝对路径，则忽略
        if (localPath.isEmpty || 
            (localPath.startsWith('/') && localPath.length == 1) ||
            (!localPath.startsWith('/') && !localPath.contains(':'))) {
          // 无效的路径格式，返回错误提示
          return Container(
            margin: const EdgeInsets.only(bottom: 8),
            padding: const EdgeInsets.all(16),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(Icons.broken_image, color: Colors.grey[400]),
                const SizedBox(height: 8),
                Text(
                  '无效的图片路径',
                  style: TextStyle(
                    color: Colors.grey[600],
                    fontSize: 12,
                  ),
                ),
              ],
            ),
          );
        }
      }
      
      return Container(
        margin: const EdgeInsets.only(bottom: 8),
        constraints: const BoxConstraints(
          maxWidth: 250,
          maxHeight: 300,
        ),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(8),
          border: Border.all(
            color: Colors.grey[300]!,
            width: 1,
          ),
        ),
        child: ClipRRect(
          borderRadius: BorderRadius.circular(8),
          child: Image.file(
            File(localPath),
            fit: BoxFit.cover,
            errorBuilder: (context, error, stackTrace) {
              return Container(
                padding: const EdgeInsets.all(16),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Icon(Icons.broken_image, color: Colors.grey[400]),
                    const SizedBox(height: 8),
                    Text(
                      '图片加载失败',
                      style: TextStyle(
                        color: Colors.grey[600],
                        fontSize: 12,
                      ),
                    ),
                  ],
                ),
              );
            },
          ),
        ),
      );
    }

    // 使用本地缓存的图片（网络图片）
    return _CachedImageWidget(imageUrl: imageUrl);
  }

  Widget _buildFilePreview(BuildContext context, Color textColor) {
    final fileUrlToUse = fileUrl ?? _extractFileUrl();
    
    if (fileUrlToUse.isEmpty) {
      return Container(
        margin: const EdgeInsets.only(bottom: 8),
        padding: const EdgeInsets.all(12),
        decoration: BoxDecoration(
          color: Colors.grey[100],
          borderRadius: BorderRadius.circular(8),
          border: Border.all(
            color: Colors.grey[300]!,
            width: 1,
          ),
        ),
        child: Row(
          children: [
            Icon(
              _getFileIcon(),
              color: textColor,
              size: 24,
            ),
            const SizedBox(width: 12),
            Expanded(
              child: Text(
                _getDisplayFileName(),
                style: TextStyle(
                  color: textColor.withOpacity(0.6),
                  fontSize: 14,
                ),
                maxLines: 2,
                overflow: TextOverflow.ellipsis,
              ),
            ),
          ],
        ),
      );
    }

    // 使用本地缓存的文件
    return _CachedFileWidget(
      fileUrl: fileUrlToUse,
      fileName: fileName,
      fileType: fileType,
      textColor: textColor,
      getFileIcon: _getFileIcon,
      getDisplayFileName: _getDisplayFileName,
    );
  }

  Widget _buildMarkdownContent(
    BuildContext context,
    Color backgroundColor,
    Color textColor,
  ) {
    return MarkdownBody(
      data: content,
      styleSheet: MarkdownStyleSheet(
          // 文本样式
          p: TextStyle(
            color: textColor,
            fontSize: 15,
            height: 1.5,
          ),
          // 链接样式
          a: TextStyle(
            color: isSent ? Colors.white70 : Colors.blue[700]!,
            decoration: TextDecoration.underline,
          ),
          // 代码样式
          code: TextStyle(
            color: textColor,
            backgroundColor: Colors.black.withOpacity(0.1),
            fontFamily: 'monospace',
            fontSize: 13,
          ),
          // 代码块样式
          codeblockDecoration: BoxDecoration(
            color: Colors.black.withOpacity(0.1),
            borderRadius: BorderRadius.circular(4),
          ),
          codeblockPadding: const EdgeInsets.all(12),
          // 列表样式
          listBullet: TextStyle(color: textColor),
          // 标题样式
          h1: TextStyle(
            color: textColor,
            fontSize: 20,
            fontWeight: FontWeight.bold,
          ),
          h2: TextStyle(
            color: textColor,
            fontSize: 18,
            fontWeight: FontWeight.bold,
          ),
          h3: TextStyle(
            color: textColor,
            fontSize: 16,
            fontWeight: FontWeight.bold,
          ),
          // 引用样式
          blockquote: TextStyle(
            color: textColor.withOpacity(0.8),
            fontStyle: FontStyle.italic,
          ),
          blockquoteDecoration: BoxDecoration(
            border: Border(
              left: BorderSide(
                color: textColor.withOpacity(0.3),
                width: 4,
              ),
            ),
          ),
          blockquotePadding: const EdgeInsets.only(left: 12),
          // 水平线样式
          horizontalRuleDecoration: BoxDecoration(
            border: Border(
              top: BorderSide(
                color: textColor.withOpacity(0.2),
                width: 1,
              ),
            ),
          ),
      ),
      onTapLink: (text, href, title) async {
          if (href != null) {
            final uri = Uri.tryParse(href);
            if (uri != null && await canLaunchUrl(uri)) {
              await launchUrl(uri, mode: LaunchMode.externalApplication);
            }
          }
        },
      imageBuilder: (uri, title, alt) {
          // 处理图片链接
          return GestureDetector(
            onTap: () {
              // TODO: 打开图片查看器
            },
            child: CachedNetworkImage(
              imageUrl: uri.toString(),
              fit: BoxFit.cover,
              errorWidget: (context, url, error) => Icon(
                Icons.broken_image,
                color: textColor.withOpacity(0.5),
              ),
            ),
          );
        },
    );
  }
}

/// 使用本地缓存的图片组件
class _CachedImageWidget extends StatefulWidget {
  final String imageUrl;

  const _CachedImageWidget({required this.imageUrl});

  @override
  State<_CachedImageWidget> createState() => _CachedImageWidgetState();
}

class _CachedImageWidgetState extends State<_CachedImageWidget> {
  String? _localPath;
  bool _isLoading = true;
  bool _hasError = false;

  @override
  void initState() {
    super.initState();
    _loadImage();
  }

  Future<void> _loadImage() async {
    try {
      // 检查是否是本地文件路径（file:// 或绝对路径）
      if (widget.imageUrl.startsWith('file://') || 
          widget.imageUrl.startsWith('/') && !widget.imageUrl.startsWith('http')) {
        // 处理 file:// 协议
        String localPath = widget.imageUrl;
        if (localPath.startsWith('file://')) {
          localPath = localPath.substring(7); // 移除 file:// 前缀
          // 检查路径是否有效（file:///screenshot.png 这种格式无效）
          // 如果移除 file:// 后路径不是有效的绝对路径，则忽略
          if (localPath.isEmpty || 
              (localPath.startsWith('/') && localPath.length == 1) ||
              (!localPath.startsWith('/') && !localPath.contains(':'))) {
            // 无效的路径格式
            setState(() {
              _hasError = true;
              _isLoading = false;
            });
            return;
          }
        }
        
        // 检查文件是否存在
        final file = File(localPath);
        if (await file.exists()) {
          setState(() {
            _localPath = localPath;
            _isLoading = false;
          });
        } else {
          setState(() {
            _hasError = true;
            _isLoading = false;
          });
        }
        return;
      }
      
      final imageCacheService = ServiceLocator().imageCacheService;
      
      // 先检查本地是否有缓存
      final cachedPath = await imageCacheService.getLocalImagePath(widget.imageUrl);
      
      if (cachedPath != null && await File(cachedPath).exists()) {
        // 本地有缓存，直接使用
        setState(() {
          _localPath = cachedPath;
          _isLoading = false;
        });
      } else {
        // 本地没有缓存，下载并缓存
        final downloadedPath = await imageCacheService.downloadAndCacheImage(widget.imageUrl);
        
        if (downloadedPath != null && await File(downloadedPath).exists()) {
          setState(() {
            _localPath = downloadedPath;
            _isLoading = false;
          });
        } else {
          setState(() {
            _hasError = true;
            _isLoading = false;
          });
        }
      }
    } catch (e) {
      setState(() {
        _hasError = true;
        _isLoading = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.only(bottom: 8),
      constraints: const BoxConstraints(
        maxWidth: 250,
        maxHeight: 300,
      ),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(8),
        border: Border.all(
          color: Colors.grey[300]!,
          width: 1,
        ),
      ),
      child: ClipRRect(
        borderRadius: BorderRadius.circular(8),
        child: _isLoading
            ? Container(
                padding: const EdgeInsets.all(16),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    CircularProgressIndicator(
                      strokeWidth: 2,
                      color: Colors.grey[400],
                    ),
                    const SizedBox(height: 8),
                    Text(
                      '加载中...',
                      style: TextStyle(
                        color: Colors.grey[600],
                        fontSize: 12,
                      ),
                    ),
                  ],
                ),
              )
            : _hasError || _localPath == null
                ? Container(
                    padding: const EdgeInsets.all(16),
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Icon(Icons.broken_image, color: Colors.grey[400]),
                        const SizedBox(height: 8),
                        Text(
                          '图片加载失败',
                          style: TextStyle(
                            color: Colors.grey[600],
                            fontSize: 12,
                          ),
                        ),
                      ],
                    ),
                  )
                : Image.file(
                    File(_localPath!),
                    fit: BoxFit.cover,
                    errorBuilder: (context, error, stackTrace) {
                      return Container(
                        padding: const EdgeInsets.all(16),
                        child: Column(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            Icon(Icons.broken_image, color: Colors.grey[400]),
                            const SizedBox(height: 8),
                            Text(
                              '图片加载失败',
                              style: TextStyle(
                                color: Colors.grey[600],
                                fontSize: 12,
                              ),
                            ),
                          ],
                        ),
                      );
                    },
                  ),
      ),
    );
  }
}

/// 使用本地缓存的文件组件
class _CachedFileWidget extends StatefulWidget {
  final String fileUrl;
  final String? fileName;
  final String? fileType;
  final Color textColor;
  final IconData Function() getFileIcon;
  final String Function() getDisplayFileName;

  const _CachedFileWidget({
    required this.fileUrl,
    this.fileName,
    this.fileType,
    required this.textColor,
    required this.getFileIcon,
    required this.getDisplayFileName,
  });

  @override
  State<_CachedFileWidget> createState() => _CachedFileWidgetState();
}

class _CachedFileWidgetState extends State<_CachedFileWidget> {
  String? _localPath;
  bool _isLoading = true;
  bool _hasError = false;

  @override
  void initState() {
    super.initState();
    _loadFile();
  }

  Future<void> _loadFile() async {
    try {
      final imageCacheService = ServiceLocator().imageCacheService;
      
      // 先检查本地是否有缓存
      final cachedPath = await imageCacheService.getLocalFilePath(widget.fileUrl);
      
      if (cachedPath != null && await File(cachedPath).exists()) {
        // 本地有缓存，直接使用
        setState(() {
          _localPath = cachedPath;
          _isLoading = false;
        });
      } else {
        // 本地没有缓存，下载并缓存
        final downloadedPath = await imageCacheService.downloadAndCacheFile(widget.fileUrl);
        
        if (downloadedPath != null && await File(downloadedPath).exists()) {
          setState(() {
            _localPath = downloadedPath;
            _isLoading = false;
          });
        } else {
          setState(() {
            _hasError = true;
            _isLoading = false;
          });
        }
      }
    } catch (e) {
      setState(() {
        _hasError = true;
        _isLoading = false;
      });
    }
  }

  Future<void> _openFile() async {
    if (_localPath == null || !await File(_localPath!).exists()) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('文件未下载完成，请稍候再试'),
            duration: const Duration(seconds: 2),
          ),
        );
      }
      return;
    }

    try {
      // 使用 file_picker 或 url_launcher 打开文件
      // 注意：在移动设备上，可能需要使用其他方式打开文件
      final uri = Uri.file(_localPath!);
      if (await canLaunchUrl(uri)) {
        await launchUrl(uri, mode: LaunchMode.externalApplication);
      } else {
        // 如果无法直接打开，尝试使用原始 URL
        final originalUri = Uri.parse(widget.fileUrl);
        if (await canLaunchUrl(originalUri)) {
          await launchUrl(originalUri, mode: LaunchMode.externalApplication);
        } else {
          if (mounted) {
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(
                content: Text('无法打开文件: ${widget.getDisplayFileName()}'),
                duration: const Duration(seconds: 2),
              ),
            );
          }
        }
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('打开文件失败: $e'),
            duration: const Duration(seconds: 2),
          ),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.only(bottom: 8),
      padding: const EdgeInsets.all(12),
      decoration: BoxDecoration(
        color: Colors.grey[100],
        borderRadius: BorderRadius.circular(8),
        border: Border.all(
          color: Colors.grey[300]!,
          width: 1,
        ),
      ),
      child: InkWell(
        onTap: _isLoading || _hasError ? null : _openFile,
        borderRadius: BorderRadius.circular(8),
        child: Row(
          children: [
            if (_isLoading)
              SizedBox(
                width: 24,
                height: 24,
                child: CircularProgressIndicator(
                  strokeWidth: 2,
                  color: widget.textColor.withOpacity(0.6),
                ),
              )
            else
              Icon(
                widget.getFileIcon(),
                color: widget.textColor,
                size: 24,
              ),
            const SizedBox(width: 12),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    widget.getDisplayFileName(),
                    style: TextStyle(
                      color: _isLoading || _hasError
                          ? widget.textColor.withOpacity(0.6)
                          : widget.textColor,
                      fontSize: 14,
                      fontWeight: _isLoading || _hasError
                          ? FontWeight.normal
                          : FontWeight.w500,
                      decoration: _isLoading || _hasError
                          ? null
                          : TextDecoration.underline,
                    ),
                    maxLines: 2,
                    overflow: TextOverflow.ellipsis,
                  ),
                  if (widget.fileType != null && widget.fileType!.isNotEmpty) ...[
                    const SizedBox(height: 4),
                    Text(
                      widget.fileType!,
                      style: TextStyle(
                        color: widget.textColor.withOpacity(0.6),
                        fontSize: 12,
                      ),
                    ),
                  ],
                  if (_isLoading) ...[
                    const SizedBox(height: 4),
                    Text(
                      '下载中...',
                      style: TextStyle(
                        color: widget.textColor.withOpacity(0.6),
                        fontSize: 11,
                      ),
                    ),
                  ],
                  if (_hasError) ...[
                    const SizedBox(height: 4),
                    Text(
                      '下载失败',
                      style: TextStyle(
                        color: Colors.red.withOpacity(0.7),
                        fontSize: 11,
                      ),
                    ),
                  ],
                ],
              ),
            ),
            if (!_isLoading && !_hasError && _localPath != null)
              Icon(
                Icons.download_done,
                color: widget.textColor.withOpacity(0.6),
                size: 20,
              )
            else if (!_isLoading && !_hasError)
              Icon(
                Icons.download,
                color: widget.textColor.withOpacity(0.6),
                size: 20,
              ),
          ],
        ),
      ),
    );
  }
}

